﻿using AutoMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Http.Headers;
using System.Security;
using System.Threading.Tasks;

using KC.Common;
using KC.Common.FileHelper;
using KC.Framework.Base;
using KC.Framework.Extension;
using KC.Framework.Tenant;
using KC.MVC.Core.Result;
using KC.Service.Core;
using KC.Service.Core.WebApiService.Business;
using KC.Service.Core.DTO.Search;
using KC.Service.Storage.Util;
using KC.DTO.Core;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace KC.MVC.Core.Controllers
{
    public abstract class TenantWebBaseController : WebBaseController
    {
        #region Service：KC.Service.Account.Util.UnityContainerUtil.InitUnityContainer(Container)

        protected IAccountApiService AccountApiService
        {
            get
            {
                return ServiceProvider.GetService<IAccountApiService>();
            }
        }

        protected IDictionaryApiService DictionaryApiService
        {
            get
            {
                return ServiceProvider.GetService<IDictionaryApiService>();
            }
        }

        protected KC.Service.Storage.IStorageQueueService StorageQueueService
        {
            get
            {
                //TODO: Storage with TenantName
                return ServiceProvider.GetService<KC.Service.Storage.IStorageQueueService>();
            }
        }

        #endregion

        protected ITenantUserApiService TenantStore => ServiceProvider.GetService<ITenantUserApiService>();
        
        protected TenantWebBaseController(
            Tenant tenant, 
            IServiceProvider serviceProvider,
            ILogger logger)
            : base(serviceProvider, logger)
        {
            Tenant = tenant;
        }

        protected bool IsEnbledFlow()
        {
            return AccountApiService.GetIsEnabledWorkFlow(CurrentOperationApplicationId).Result;
        }

        #region Tenant Info

        private string _tenantName;
        /// <summary>
        /// 租户编码：UR2015060600001
        /// </summary>
        public string TenantName
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(this._tenantName))
                    return this._tenantName.ToLower();

                return null;
            }

            set
            {
                this._tenantName = value;
                ViewBag.TenantName = value;
            }
        }

        private string _tenantNickName;
        /// <summary>
        ///存的是NickName或者TenantName,看域名
        /// </summary>
        public string TenantNickName
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(this._tenantNickName))
                    return this._tenantNickName.ToLower();
                return null;
            }

            set
            {
                this._tenantNickName = value;
                ViewBag.TenantNickName = value;
            }
        }

        private string _tenantDisplayName;
        /// <summary>
        /// 租户的中文名称
        /// </summary>
        public string TenantDisplayName
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(this._tenantDisplayName))
                    return this._tenantDisplayName.ToLower();

                return null;
            }

            set
            {
                this._tenantDisplayName = value;
                ViewBag.TenantDisplayName = value;
            }
        }

        private Tenant _tenant;
        public Tenant Tenant
        {
            get
            {
                if (this._tenant != null)
                    return this._tenant;

                return null;
            }

            set
            {
                this._tenant = value;
                this.TenantName = value?.TenantName;
                this.TenantNickName = value?.NickName;
                this.TenantDisplayName = value?.TenantDisplayName;

                ViewBag.Tenant = value;
            }
        }

        /// <summary>
        /// 是否为Dba管理系统
        /// </summary>
        public bool IsSupperAdmin
        {
            get
            {
                return TenantName.Equals(TenantConstant.DbaTenantName, StringComparison.OrdinalIgnoreCase);
            }
        }
        /// <summary>
        /// 是否为当前租户的内部用户
        /// </summary>
        public bool IsTenantUser
        {
            get { return TenantName.Equals(CurrentUserTenantName, StringComparison.OrdinalIgnoreCase); }
        }
        /// <summary>
        /// 是否为企业用户
        /// </summary>
        public bool IsEnterprise
        {
            get
            {
                return Tenant.TenantType == TenantType.SupplyChainFinance ||
                       Tenant.TenantType == TenantType.StoreCredit;
            }
        }


        #endregion Tenant Info

        #region Captcha
        private const string CaptchaSessionKey = "kcloudy-captchacode";
        /// <summary>
        /// 获取Captcha图片，并将Code保存在Cookies中，Cookies的key为基类中的常量：CaptchaSessionKey<br/>
        /// 前端使用实例： <img src="/Home/GetCaptchaImage" /> 
        /// 后端以Post方式，验证方法如下：VerifyCaptcha（VerifyRequest model）
        /// 
        /// 使用范例：http://resource.kcloudy.com/Home/Captcha
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> GetCaptchaImage()
        {
            var model = await CaptchaFactory.Instance.CreateAsync();
            ViewBag.Captcha = CaptchaSessionKey;
            Response.Cookies.Append(CaptchaSessionKey, model.Answer);
            return File(model.Image, model.ContentType);
        }

        /// <summary>
        /// 验证码的校验，验证结果对象为：VerifyResponse
        /// </summary>
        /// <param name="model">
        /// VerifyRequest
        ///     Answer：答案
        ///     Captcha：Cookie中对应Captcha的值，即GetCaptchaImage时，返回前端Cookies中包含包含的Captcha的值，前端获取该Cookie值的代码：
        ///     function getCookie() {
        ///           var strCookie = document.cookie;
        ///           var arrCookie = strCookie.split("; ");
        ///           for (var i = 0; i < arrCookie.length; i++) {
        ///               var arr = arrCookie[i].split("=");
        ///               if (arr[0] === '@ViewBag.Captcha') return arr[1];
        ///           }
        ///          return "";
        ///      }
        /// </param>
        /// <returns>
        ///     VerifyResponse
        ///     code = 100 : message = 验证成功
        ///     code = 101 : message = 验证失败,参数为空
        ///     code = 102 : message = 验证码失效,一个验证码只能调用一次接口
        ///     code = 103 : message = 验证码失效,验证码解密失败
        ///     code = 104 : message = 验证码失效,验证码解密失败
        ///     code = 105 : message = 验证失败，验证码不匹配
        /// </returns>
        [HttpPost]
        public async Task<IActionResult> VerifyCaptcha([FromBody] VerifyRequest model)
        {
            //VerifyResponse
            var response = await CaptchaFactory.Instance.VerifyAsync(model);

            return Json(response);
        }
        #endregion

        #region Upload

        /// <summary>
        /// UEdit config
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Upload(string parm)
        {
            if ("config".Equals(parm))
            {
                var domainName = GlobalConfig.GetDocumentApiUrl(Tenant.TenantName);
                var configPath = ServerPath + "/wwwroot/js/ueditor/config.json";
                var configContent = System.IO.File.ReadAllText(configPath);
                configContent = configContent.Replace("{ApiDomain}", domainName).Replace("{imageMaxSize}", (GlobalConfig.UploadConfig.ImageMaxSize * 1024 * 1024).ToString()).Replace("{fileMaxSize}", (GlobalConfig.UploadConfig.FileMaxSize * 1024 * 1024).ToString());
                return Content(SerializeHelper.ToJson(JObject.Parse(configContent)));
            }

            return Json(new
            {
                success = false,
                message = "请选择上传文件",
                state = "请选择上传文件",
                url = string.Empty,
                id = string.Empty,
                title = string.Empty,
                original = string.Empty,
                error = "请选择上传文件"
            });
        }

        //[AuthenticateAndAuthorizeTenant]
        [HttpPost]
        [RequestSizeLimit(100_000_000)] //最大100m左右
        //[DisableRequestSizeLimit]  //或者取消大小的限制
        //[MVC.Core.Extension.PermissionFilter("文件上传", "文件上传", "Home/Upload", ApplicationConstant.DefaultAuthorityId,
        //    DefaultRoleId = RoleConstants.AdminRoleId, Order = 1, IsPage = true, ResultType = ResultType.ActionResult, AuthorityId = ApplicationConstant.DefaultAuthorityId)]
        public IActionResult Upload()
        {
            string parm = Request.Query["parm"];
            IFormFile file = Request.Form.Files.Count != 0 ? Request.Form.Files[0] : null;
            if ("config".Equals(parm))
            {
                return Upload(parm);
            }
            else if ("uploadimage".Equals(parm))
            {
                return UploadImage(file, CurrentUserId);
            }
            else if ("listimage".Equals(parm))
            {
                return ListImage(CurrentUserId);
            }
            else if ("uploadfile".Equals(parm))
            {
                return UploadFile(file, CurrentUserId);
            }
            else if ("uplistfile".Equals(parm))
            {
                return ListFile(CurrentUserId);
            }

            return null;
        }

        private JsonResult UploadImage(IFormFile file, string userId)
        {
            #region 检测：文件限制

            if (file == null)
            {
                return Json(new
                {
                    success = false,
                    message = "请选择上传文件",
                    state = "请选择上传文件",
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = "请选择上传文件"
                });
            }

            string fileName = file.FileName;
            string extensionStr = fileName.Remove(0, fileName.LastIndexOf('.') + 1).ToLower();
            var parsedContentDisposition = ContentDispositionHeaderValue.Parse(file.ContentDisposition);
            fileName = parsedContentDisposition.FileName.Trim('"');

            //检查扩展名
            if (!GlobalConfig.UploadConfig.ImageExt.Split(',').Contains(extensionStr))
            {
                var msg = "不允许上传此类型的文件。 \n只允许" + GlobalConfig.UploadConfig.ImageExt + " 格式。";
                return Json(new
                {
                    success = false,
                    message = msg,
                    state = msg,
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = msg
                });
            }

            //文件大小
            if (file.Length > GlobalConfig.UploadConfig.ImageMaxSize * 1024 * 1024)
            {
                return Json(new
                {
                    success = false,
                    message = "文件大小超过限制",
                    state = "文件大小超过限制",
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = "文件大小超过限制"
                });
            }

            #endregion 检测：文件限制

            #region 上传图片

            try
            {
                var blobId = Guid.NewGuid().ToString();
                var fileType = FileType.Image.ToString();
                var fileFormat = MimeTypeHelper.GetImageFormatByExt(extensionStr).ToString();
                var buffer = new byte[file.Length];
                using (var reader = file.OpenReadStream())
                {
                    reader.Read(buffer, 0, buffer.Length);
                }
                BlobUtil.SaveBlob(Tenant, userId, buffer, blobId, fileType, fileFormat, fileName);

                return Json(new
                {
                    success = true,
                    message = string.Empty,
                    state = "SUCCESS",
                    url = "?id=" + blobId + "&uId=" + userId,
                    id = blobId,
                    title = fileName,
                    original = fileName,
                    error = string.Empty
                });
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, ex.Message);
                return Json(new
                {
                    success = false,
                    message = ex.Message,
                    state = ex.Message,
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = ex.Message
                });
            }

            #endregion 上传图片
        }
        private JsonResult ListImage(string userId)
        {
            var start = String.IsNullOrEmpty(Request.Query["start"]) ? 0 : Convert.ToInt32(Request.Query["start"]);

            var fileList = BlobUtil.GetTenantBlobIdsWithType(Tenant, userId, FileType.Image).ToList();

            return Json(new
            {
                success = true,
                message = string.Empty,
                state = "SUCCESS",
                list = fileList.Select(x => new { url = string.Format("?id={0}&uId={1}", x, userId) }),
                ids = fileList.Select(x => new { blobId = x }),
                start = start,
                size = 20,
                total = fileList.Count
            });
        }
        private JsonResult UploadFile(IFormFile file, string userId)
        {
            #region 检查：文件限制

            if (file == null)
            {
                return Json(new
                {
                    success = false,
                    message = "请选择上传文件",
                    state = "请选择上传文件",
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = "请选择上传文件"
                });
            }

            string fileName = file.FileName;
            string extensionStr = fileName.Remove(0, fileName.LastIndexOf('.') + 1).ToLower();

            var allowExtension =
                GlobalConfig.UploadConfig.FileExt.Split(',').Concat(GlobalConfig.UploadConfig.ImageExt.Split(','));

            //检查扩展名
            if (!allowExtension.Contains(extensionStr))
            {
                var msg = "不允许上传此类型的文件。 \n只允许" + GlobalConfig.UploadConfig.ImageExt + "," +
                          GlobalConfig.UploadConfig.FileExt + " 格式。";
                return Json(new
                {
                    success = false,
                    message = msg,
                    state = msg,
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = msg
                });
            }

            //文件大小
            if (file.Length > GlobalConfig.UploadConfig.FileMaxSize * 1024 * 1024)
            {
                return Json(new
                {
                    success = false,
                    message = "文件大小超过限制",
                    state = "文件大小超过限制",
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = "文件大小超过限制"
                });
            }

            #endregion 检查：文件限制

            #region 上传附件

            try
            {
                var blobId = Guid.NewGuid().ToString();
                var fileType = MimeTypeHelper.GetFileType(extensionStr).ToString();
                var fileFormat = MimeTypeHelper.GetDocFormatByExt(extensionStr).ToString();
                var buffer = new byte[file.Length];
                using (var reader = file.OpenReadStream())
                {
                    reader.Read(buffer, 0, buffer.Length);
                }

                BlobUtil.SaveBlob(Tenant, userId, buffer, blobId, fileType, fileFormat, fileName);

                return Json(new
                {
                    success = true,
                    message = string.Empty,
                    state = "SUCCESS",
                    url = "?id=" + blobId + "&uId=" + userId,
                    id = blobId,
                    title = fileName,
                    original = fileName,
                    error = string.Empty
                });
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, ex.Message);
                return Json(new
                {
                    success = false,
                    message = ex.Message,
                    state = ex.Message,
                    url = string.Empty,
                    id = string.Empty,
                    title = string.Empty,
                    original = string.Empty,
                    error = ex.Message
                });
            }

            #endregion 上传附件
        }
        private JsonResult ListFile(string userId)
        {
            var start = String.IsNullOrEmpty(Request.Query["start"]) ? 0 : Convert.ToInt32(Request.Query["start"]);

            var fileList = new List<String>();

            fileList = BlobUtil.GetTenantBlobIdsWithType(Tenant, userId, FileType.Excel).ToList();

            return Json(new
            {
                success = true,
                message = string.Empty,
                state = "SUCCESS",
                list = fileList.Select(x => new { url = string.Format("?id={0}&uId={1}", x, userId) }),
                ids = fileList.Select(x => new { blobId = x }),
                start = start,
                size = 20,
                total = fileList.Count
            });
        }

        [HttpPost]
        [RequestSizeLimit(100_000_000)] //最大100m左右
        //[DisableRequestSizeLimit]  //或者取消大小的限制
        //[MVC.Core.Extension.PermissionFilter("文件上传", "文件上传", "Home/UploadFileToTemp", ApplicationConstant.DefaultAuthorityId,
        //    DefaultRoleId = RoleConstants.AdminRoleId, Order = 1, IsPage = true, ResultType = ResultType.ActionResult, AuthorityId = ApplicationConstant.DefaultAuthorityId)]
        public IActionResult UploadFileToTemp()
        {
            var files = Request.Form.Files;
            if (files.Count == 0)
                return Json(new { success = false, message = "请选择上传文件" });

            #region 传入参数
            string uploadType = null;
            string md5 = null;
            string tenatName = null;
            string userId = null;
            string blobId = null;
            string uploadFileName = null;
            string extensionStr = null;
            bool isWatermake = false;
            bool isTopdf = false;
            long fileSize = 0;

            foreach (var form in Request.Form)
            {
                if(form.Key.Equals("uploadType", StringComparison.OrdinalIgnoreCase))
                {
                    uploadType = form.Value;
                }
                else if(form.Key.Equals("md5", StringComparison.OrdinalIgnoreCase))
                {
                    md5 = form.Value;
                }
                else if (form.Key.Equals("tenatName", StringComparison.OrdinalIgnoreCase))
                {
                    tenatName = form.Value;
                }
                else if (form.Key.Equals("userId", StringComparison.OrdinalIgnoreCase))
                {
                    userId = form.Value;
                }
                else if (form.Key.Equals("blobId", StringComparison.OrdinalIgnoreCase))
                {
                    blobId = form.Value;
                }
                else if (form.Key.Equals("name", StringComparison.OrdinalIgnoreCase))
                {
                    uploadFileName = form.Value;
                }
                else if (form.Key.Equals("ext", StringComparison.OrdinalIgnoreCase))
                {
                    extensionStr = form.Value;
                }
                else if (form.Key.Equals("isWatermake", StringComparison.OrdinalIgnoreCase))
                {
                    bool.TryParse(form.Value, out isWatermake);
                }
                else if (form.Key.Equals("isTopdf", StringComparison.OrdinalIgnoreCase))
                {
                    bool.TryParse(form.Value, out isTopdf);
                }
                else if (form.Key.Equals("size", StringComparison.OrdinalIgnoreCase))
                {
                    long.TryParse(form.Value, out fileSize);
                }
            }
            #endregion

            try
            {
                IFormFile file = files[0];
                switch (uploadType.ToLower())
                {
                    case "uploadimage":
                        //检查扩展名
                        if (!GlobalConfig.UploadConfig.ImageExt.Split(',').Contains(extensionStr))
                            return Json(new { success = false, error = 1, message = "不允许上传此类型的文件。 \n只允许" + GlobalConfig.UploadConfig.ImageExt + " 格式。" });

                        //文件大小
                        if (fileSize > GlobalConfig.UploadConfig.ImageMaxSize * 1024 * 1024)
                            return Json(new { success = false, error = 1, message = "文件大小超过限制" });
                        break;

                    default:
                        //文件大小
                        if (fileSize > GlobalConfig.UploadConfig.FileMaxSize * 1024 * 1024)
                            return Json(new { success = false, error = 1, message = "文件大小超过限制" });
                        break;
                }
                //如果进行了分片
                if (Request.Form.Keys.Any(m => m == "chunk"))
                {
                    //获得上传的分片数据流
                    var chunkFile = Request.Body;
                    if (null == chunkFile)
                    {
                        return Json(new { success = false, message = "上传的文件不能为空" });
                    }

                    string path = Path.Combine(TempDir, md5);
                    if (CreateFileFolder(path))
                    {
                        //取得chunk和chunks
                        int chunk = Convert.ToInt32(Request.Form["chunk"]);//当前分片在上传分片中的顺序（从0开始）
                        //int chunks = Convert.ToInt32(Request.Form["chunks"]);//总分片数

                        var fileName = Path.Combine(path, chunk.ToString());
                        using (var addFile = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                        {
                            using (var addWriter = new BinaryWriter(addFile))
                            {
                                using (Stream stream = chunkFile)
                                {
                                    using (var tempReader = new BinaryReader(stream))
                                    {
                                        addWriter.Write(tempReader.ReadBytes((int)stream.Length));
                                    }
                                }

                                return Json(new
                                {
                                    success = true
                                });
                            }
                        }
                    }
                    return Json(new
                    {
                        success = false
                    });
                }
                else
                {
                    Tenant blobTenant;
                    if (string.IsNullOrWhiteSpace(tenatName))
                    {
                        blobTenant = Tenant;
                    }
                    else
                    {
                        if (TenantName.Equals(tenatName, StringComparison.OrdinalIgnoreCase))
                        {
                            blobTenant = Tenant;
                        }
                        else
                        {
                            blobTenant = TenantStore.GetTenantByName(tenatName).Result ?? Tenant;
                        }
                    }

                    var blobUserId = string.IsNullOrWhiteSpace(userId) ? CurrentUserId : userId;
                    blobId = string.IsNullOrWhiteSpace(blobId) ? Guid.NewGuid().ToString() : blobId;

                    var container = blobTenant.TenantName;

                    switch (uploadType.ToLower())
                    {
                        case "uploadimage":
                            var fileType = FileType.Image.ToString();
                            var fileFormat = MimeTypeHelper.GetImageFormatByExt(extensionStr).ToString();
                            if (isWatermake)
                            {
                                var addWatermarkResult = AddWatermarkToImage(file, blobId, extensionStr, blobTenant.TenantDisplayName);
                                isWatermake = addWatermarkResult.Item1;
                                if (addWatermarkResult.Item1)
                                {
                                    BlobUtil.SaveBlob(Tenant, blobUserId, addWatermarkResult.Item2, blobId, fileType, fileFormat, uploadFileName, true);
                                    CleanTempFile(addWatermarkResult.Item2);
                                }
                            }
                            if (!isWatermake)
                            {
                                var buffer = new byte[file.Length];
                                using (var reader = file.OpenReadStream())
                                {
                                    reader.Read(buffer, 0, buffer.Length);
                                }
                                BlobUtil.SaveBlob(Tenant, blobUserId, buffer, blobId, fileType, fileFormat, uploadFileName, true);
                            }

                            return Json(new
                            {
                                success = true,
                                message = string.Empty,
                                url = TempImgUrl(blobId),
                                id = blobId,
                            });
                        default:
                            var fileType1 = MimeTypeHelper.GetFileType(extensionStr).ToString();
                            var fileFormat1 = MimeTypeHelper.GetDocFormatByExt(extensionStr).ToString();
                            var fileBuffer = new byte[file.Length];
                            using (var reader = file.OpenReadStream())
                            {
                                reader.Read(fileBuffer, 0, fileBuffer.Length);
                            }
                            if (isTopdf && fileType1 != "PDF")
                            {
                                //var stream = new MemoryStream(fileBuffer);
                                //var doc = new Spire.Doc.Document(stream);
                                //var docFormat = Spire.Doc.FileFormat.Doc;
                                //Enum.TryParse(fileFormat1, out docFormat);
                                //doc.LoadFromStream(stream, docFormat);
                                //var pdfSteam = new MemoryStream();
                                ////转换PDF，并以流的形式保存
                                //doc.SaveToStream(pdfSteam, Spire.Doc.FileFormat.PDF);
                                //var spireDocHelper = new SpireDocHelper();
                                //var pdfSteam = spireDocHelper.ConvertToPdfStream(fileFormat1, fileBuffer);
                                //BlobUtil.SaveBlob(Tenant, CurrentUserId, pdfSteam.ToArray(), blobId, "PDF", "Pdf", uploadFileName.Replace("docx", "pdf").Replace("doc", "pdf"), true);
                            }
                            else
                            {
                                BlobUtil.SaveBlob(Tenant, blobUserId, fileBuffer, blobId, fileType1, fileFormat1, uploadFileName, true);
                            }
                            return Json(new
                            {
                                success = true,
                                message = string.Empty,
                                url = TempFileUrl(blobId),
                                id = blobId,
                            });
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, ex.Message);
                return Json(new { success = false, message = ex.Message });
            }
        }

        /// <summary>
        /// 分片验证,验证对应分片文件是否存在，大小是否吻合
        /// </summary>
        /// <param name="name">文件md5</param>
        /// <param name="chunkIndex">分片序列</param>
        /// <param name="size">分片文件的大小</param>
        /// <returns></returns>
        [HttpGet]
        public JsonResult ChunkCheck(string name, int chunkIndex, long size)
        {
            var chunkFile = Path.Combine(TempDir, name, chunkIndex.ToString());
            //分片已存在
            if (System.IO.File.Exists(chunkFile) && size == System.IO.File.ReadAllBytes(chunkFile).LongLength)
            {
                return Json(new { ifExist = true });
            }
            //分片不存在
            return Json(new { ifExist = false });
        }

        /// <summary>
        /// 分片合并操作
        /// 并发锁: 避免多线程同时触发合并操作
        /// 清理: 合并清理不再需要的分片文件、文件夹、tmp文件
        /// </summary>
        /// <param name="folder">分片文件所在的文件夹名称</param>
        /// <param name="name">合并后的文件名</param>
        /// <param name="chunks">分片总数</param>
        /// <param name="type">文件类型</param>
        /// <param name="blobId">文件名</param>
        /// <param name="ext">后缀名</param>
        /// <param name="userId">用户id</param>
        /// <returns></returns>
        [HttpGet]
        public JsonResult ChunksMerge(string folder, string name, int chunks, string type, string blobId, string ext, string userId)
        {
            //分片存储目录
            var chunkFileDir = Path.Combine(TempDir, folder);
            //分片列表
            var chunkFiles = GetChunks(chunkFileDir);

            //检查是否满足合并条件：分片数量是否足够
            if (chunks == chunkFiles.Count)
            {
                //TODO 同步指定合并的对象

                //按照名称排序文件，这里分片都是按照数字命名的
                chunkFiles = chunkFiles.OrderBy(m => int.Parse(m.Name)).ToList();
                var newFilePath = Path.Combine(TempDir, name);
                try
                {
                    foreach (var file in chunkFiles)
                    {
                        using (var chunkFile = new FileStream(file.FullName, FileMode.Open, FileAccess.Read))
                        {
                            var fsLen = (int)chunkFile.Length;
                            var heByte = new byte[fsLen];
                            chunkFile.Read(heByte, 0, fsLen);
                            using (var addFile = new FileStream(newFilePath, FileMode.Append, FileAccess.Write))
                            {
                                using (var addWriter = new BinaryWriter(addFile))
                                {
                                    addWriter.Write(heByte);
                                }
                            }
                        }
                        file.Delete();
                    }

                    //Copy
                    var blobUserId = string.IsNullOrWhiteSpace(userId) ? CurrentUserId : userId;
                    blobId = string.IsNullOrWhiteSpace(blobId) ? Guid.NewGuid().ToString() : blobId;
                    var fileType = type.ToLower()== "uploadimage" ? FileType.Image.ToString() : MimeTypeHelper.GetFileType(ext).ToString();
                    var fileFormat = MimeTypeHelper.GetImageFormatByExt(ext).ToString();
                    using (var stream = new FileStream(newFilePath, FileMode.Open, FileAccess.Read))
                    {
                        var fsLen = (int)stream.Length;
                        var heByte = new byte[fsLen];
                        stream.Read(heByte, 0, fsLen);
                        BlobUtil.SaveBlob(Tenant, blobUserId, heByte, blobId, fileType, fileFormat, name, true);
                    }
                    System.IO.File.Delete(newFilePath);
                }
                catch (Exception ex)
                {
                    return Json(new
                    {
                        success = false,
                        message = ex.Message
                    });
                }
                //清理：文件夹，tmp文件
                CleanSpace(chunkFileDir);
                return Json(new
                {
                    success = true,
                    message = string.Empty,
                    url = TempFileUrl(blobId),
                    id = blobId,
                });
            }
            return Json(new
            {
                success = false,
                message = string.Empty
            });
        }

        /// <summary>
        /// 浏览临时目录图片路径
        /// </summary>
        /// <param name="blobId"></param>
        /// <returns></returns>
        protected string TempImgUrl(string blobId)
        {
            return "/Home/ShowTempImg?id=" + blobId;
            //return Url.Action("ShowTempImg", new { id = blobId });
        }

        protected string TempFileUrl(string blobId)
        {
            return "/Home/DownloadTempFile?id=" + blobId;
            //return Url.Action("DownloadTempFile", new { id = blobId });
        }

        /// <summary>
        /// 将临时文件从临时空间转移至客户文件夹，并删除临时文件
        /// </summary>
        /// <param name="blobIds"></param>
        /// <param name="containThumbnail"></param>
        protected bool CopyTempsToClientAzureBlob(List<string> blobIds, bool containThumbnail = false)
        {
            return BlobUtil.CopyTempsToClientBlob(Tenant, blobIds, CurrentUserId, containThumbnail);
        }
        /// <summary>
        /// 将文件复制到指定客户文件夹
        /// </summary>
        /// <param name="targetTenant">指定客户</param>
        /// <param name="blobIds">文件ID</param>
        /// <param name="containThumbnail">是否包含小图标</param>
        /// <returns></returns>
        protected bool CopyBlobsToOtherClientAzure(Tenant targetTenant, List<string> blobIds, bool containThumbnail = false)
        {
            return BlobUtil.CopyBlobsToOtherClient(Tenant, targetTenant, blobIds, CurrentUserId, containThumbnail);
        }
        /// <summary>
        /// 获取指定文件的所有分片
        /// </summary>
        /// <param name="folder">文件夹路径</param>
        /// <returns></returns>
        private List<FileInfo> GetChunks(string folder)
        {
            if (Directory.Exists(folder))
                return new DirectoryInfo(folder).GetFiles().ToList();
            return new List<FileInfo>();
        }

        /// <summary>
        /// 创建存放上传的文件的文件夹
        /// </summary>
        /// <param name="name">文件夹路径</param>
        /// <returns></returns>
        private bool CreateFileFolder(string name)
        {
            //创建存放分片文件的临时文件夹
            if (!Directory.Exists(name))
            {
                try
                {
                    Directory.CreateDirectory(name);
                }
                catch (SecurityException)
                {
                    return false;
                }
            }

            var tempFile = name + ".tmp";

            if (!System.IO.File.Exists(tempFile))
            {
                try
                {
                    //创建一个对应的文件，用来记录上传分片文件的修改时间，用于清理长期未完成的垃圾分片
                    using (System.IO.File.Create(tempFile))
                    {
                    }
                }
                catch (SecurityException ex)
                {
                    Logger.LogError(ex, ex.Message);
                    return false;
                }
            }
            else
            {
                //TODO 多线程访问
                System.IO.File.SetLastWriteTimeUtc(tempFile, DateTime.UtcNow);
            }

            return true;
        }

        private void CleanSpace(string folder)
        {
            try
            {
                //删除分片文件夹
                Directory.Delete(folder);
                //删除tmp文件
                System.IO.File.Delete(folder + ".tmp");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, ex.Message);
            }
        }

        private void CleanTempFile(string filePath)
        {
            try
            {
                //删除tmp文件
                System.IO.File.Delete(filePath);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, ex.Message);
            }
        }

        private Tuple<bool, string> AddWatermarkToImage(IFormFile file, string blobId, string extensionStr, string text)
        {
            string tempFilePath = Path.Combine(TempDir, blobId + "_tmp." + extensionStr);
            string newFilePath = Path.Combine(TempDir, blobId + "." + extensionStr);
            try
            {
                using (var addFile = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write))
                {
                    using (var addWriter = new BinaryWriter(addFile))
                    {
                        using (var stream = file.OpenReadStream())
                        {
                            using (var tempReader = new BinaryReader(stream))
                            {
                                addWriter.Write(tempReader.ReadBytes((int)stream.Length));
                            }
                        }
                    }
                }
                //WatermarkHelper.AddFullWaterTextToImage(tempFilePath, newFilePath, text);
                CleanTempFile(tempFilePath);
                return new Tuple<bool, string>(true, newFilePath);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, ex.Message);
            }
            return new Tuple<bool, string>(false, newFilePath);
        }

        #endregion Upload

        #region Image

        /// <summary>
        /// 打开Image
        /// </summary>
        /// <param name="blobId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Image(string blobId, string userId)
        {
            if (string.IsNullOrEmpty(userId))
                userId = CurrentUserId;

            //var authToken = GetAuthToken(false);
            //var blob = BlobProvider.GetBlob(authToken, blobId);
            var blob = BlobUtil.GetBlobById(Tenant, userId, blobId, false);
            if (blob != null && blob.Data != null)
            {
                var eFormat = ImageFormat.Unknown;
                bool isSuccess = Enum.TryParse(blob.FileFormat, out eFormat);
                if (isSuccess)
                {
                    if (blob.FileType.Equals(FileType.Image.ToString(), StringComparison.OrdinalIgnoreCase)
                        && blob.FileFormat.Equals(ImageFormat.Unknown.ToString()))
                    {
                        var pdfPath = ServerPath + "/wwwroot/images/pdficon.png";
                        if (System.IO.File.Exists(pdfPath))
                        {
                            using (var fs = new FileStream(pdfPath, FileMode.Open))
                            {
                                byte[] buffer = new byte[fs.Length];
                                fs.Read(buffer, 0, buffer.Length);
                                return new ImageResult(buffer, eFormat);
                            }
                        }
                    }
                    else if (blob.FileType.Equals(FileType.Unknown.ToString(), StringComparison.OrdinalIgnoreCase)
                             && blob.FileFormat.Equals(ImageFormat.Unknown.ToString()))
                    {
                        return Download(blobId, userId);
                    }
                    else
                    {
                        byte[] buffer = blob.Data;
                        return new ImageResult(buffer, eFormat);
                    }
                }
            }

            return Download(blobId, userId);
        }

        [HttpGet]
        public IActionResult TempImage(string blobId, string userId)
        {
            if (string.IsNullOrEmpty(userId))
                userId = CurrentUserId;

            //var authToken = GetAuthToken(true);
            //var blob = BlobProvider.GetBlob(authToken, blobId);
            var blob = BlobUtil.GetBlobById(Tenant, userId, blobId, true);
            if (blob != null && blob.Data != null)
            {
                var eFormat = ImageFormat.Jpeg;
                bool isSuccess = Enum.TryParse(blob.FileFormat, out eFormat);
                if (isSuccess)
                {
                    if (blob.FileType.Equals(FileType.Image.ToString(), StringComparison.OrdinalIgnoreCase)
                        && blob.FileFormat.Equals(ImageFormat.Unknown.ToString()))
                    {
                        var pdfPath = ServerPath  + "/wwwroot/images/pdficon.png";
                        if (System.IO.File.Exists(pdfPath))
                        {
                            using (var fs = new FileStream(pdfPath, FileMode.Open))
                            {
                                byte[] buffer = new byte[fs.Length];
                                fs.Read(buffer, 0, buffer.Length);
                                return new ImageResult(buffer, eFormat);
                            }
                        }
                    }
                    else
                    {
                        byte[] buffer = blob.Data;
                        return new ImageResult(buffer, eFormat);
                    }
                }
            }

            return Download(blobId, userId);
        }

        //[AuthenticateAndAuthorizeTenant]
        [HttpGet]
        public IActionResult Download(string blobId, string userId)
        {
            if (string.IsNullOrEmpty(userId))
                userId = CurrentUserId;

            //var authToken = GetAuthToken(userId, false);
            //var blob = BlobProvider.GetBlob(authToken, blobId);
            var blob = BlobUtil.GetBlobById(Tenant, userId, blobId, false);
            if (blob != null && blob.Data != null)
            {
                DocFormat docFormat = DocFormat.Unknown;
                bool isSuccess = Enum.TryParse(blob.FileFormat, out docFormat);
                if (isSuccess)
                {
                    byte[] buffer = blob.Data;
                    string contentType = MimeTypeHelper.GetMineType(docFormat);

                    var stream = new MemoryStream(buffer);
                    string decodeFileName = blob.FileName.UnicodeToChinese();
                    return File(stream, contentType, decodeFileName.ReplaceLast(".", "-" + blob.Id + "."));
                }
                else
                {
                    return Json(new { ResultType = ServiceResultType.Error, Message = "不支持所保存的文件格式。" });
                }
            }
            return Json(new { ResultType = ServiceResultType.Error, Message = "未找到文件。" });
        }

        [HttpGet]
        public IActionResult DownloadTemp(string blobId, string userId)
        {
            if (string.IsNullOrEmpty(userId))
                userId = CurrentUserId;

            //var authToken = GetAuthToken(true);
            //var blob = BlobProvider.GetBlob(authToken, blobId);
            var blob = BlobUtil.GetBlobById(Tenant, userId, blobId, true);
            if (blob != null && blob.Data != null)
            {
                DocFormat docFormat = DocFormat.Doc;
                bool isSuccess = Enum.TryParse(blob.FileFormat, out docFormat);
                if (isSuccess)
                {
                    byte[] buffer = blob.Data;
                    string contentType = MimeTypeHelper.GetMineType(docFormat);

                    var stream = new MemoryStream(buffer);
                    string decodeFileName = blob.FileName.UnicodeToChinese();
                    return File(stream, contentType, decodeFileName.ReplaceLast(".", "-" + blob.Id + "."));
                }
                else
                {
                    return Json(new { ResultType = ServiceResultType.Error, Message = "不支持所保存的文件格式。" });
                }
            }
            return Json(new { ResultType = ServiceResultType.Error, Message = "未找到文件。" });
        }

        private FileResult DownloadTempFile(string blobId, string userId)
        {
            if (string.IsNullOrEmpty(userId))
                userId = CurrentUserId;

            //var authToken = GetAuthToken(true);
            //var blob = BlobProvider.GetBlob(authToken, blobId);
            var blob = BlobUtil.GetBlobById(Tenant, userId, blobId, true);
            if (blob != null && blob.Data != null)
            {
                DocFormat docFormat = DocFormat.Doc;
                bool isSuccess = Enum.TryParse(blob.FileFormat, out docFormat);
                if (isSuccess)
                {
                    byte[] buffer = blob.Data;
                    string contentType = MimeTypeHelper.GetMineType(docFormat);

                    var stream = new MemoryStream(buffer);
                    string decodeFileName = blob.FileName.UnicodeToChinese();
                    if (docFormat == DocFormat.Pdf) //TODO 其他类型
                    {
                        return File(stream, "application/pdf", decodeFileName.ReplaceLast(".", "-" + blob.Id + "."));
                    }

                    return File(stream, contentType, decodeFileName.ReplaceLast(".", "-" + blob.Id + "."));
                }
                else
                {
                    return null;
                }
            }
            return null;
        }

        /// <summary>
        /// 显示图片
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ImageResult ShowImg(string id)
        {
            return Image(id, CurrentUserId) as ImageResult;
        }

        [HttpGet]
        public ImageResult ShowTempImg(string id)
        {
            return TempImage(id, CurrentUserId) as ImageResult;
        }

        [HttpGet]
        public FileResult DownloadTempFile(string id)
        {
            return DownloadTemp(id, CurrentUserId) as FileResult;
        }

        [HttpGet]
        public FileResult ShowTempFile(string id)
        {
            return DownloadTempFile(id, CurrentUserId) as FileResult;
        }

        //private AuthToken GetAuthToken(bool isTempAuth)
        //{
        //    return BlobUtil.GetAuthToken(TenantName, CurrentUserId, isTempAuth);
        //}

        //private AuthToken GetAuthToken(string useriD, bool isTempAuth)
        //{
        //    return BlobUtil.GetAuthToken(TenantName, useriD, isTempAuth);
        //}

        #endregion Image

        #region Image & pdf & file

        protected bool IsUploads(string path)
        {
            if (!Directory.Exists(path))//如果不存在就创建file文件夹
            {
                try
                {
                    Directory.CreateDirectory(path);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, ex.Message);
                    return false;
                }
            }
            return true;
        }

        protected bool DeleteFile(string path)
        {
            if (System.IO.File.Exists(path)) //如果不存在就创建file文件夹
            {
                System.IO.File.Delete(path);
            }

            return !System.IO.File.Exists(path);
        }


        //[AuthenticateAndAuthorizeTenant]
        [HttpGet]
        public IActionResult DownloadContract(string blobId, string userId, string id = "")
        {
            if (string.IsNullOrEmpty(userId))
                userId = TenantName;
            var tenant = TenantStore.GetTenantByName(userId).Result;
            var blob = BlobUtil.GetBlobById(tenant, CurrentUserId, blobId);
            if (blob != null && blob.Data != null && blob.Data.Length > 0)
            {
                DocFormat docFormat = DocFormat.Unknown;
                bool isSuccess = Enum.TryParse(blob.FileFormat, out docFormat);
                if (isSuccess)
                {

                    byte[] buffer = blob.Data;
                    string contentType = MimeTypeHelper.GetMineType(docFormat);

                    var stream = new MemoryStream(buffer);
                    string decodeFileName = blob.FileName.UnicodeToChinese();
                    if (!string.IsNullOrEmpty(id))
                    {
                        //var dlog = new ContractGroupOperationLogDTO()
                        //{
                        //    ContractGroupId = new Guid(id),
                        //    ContractGroupProgress = ContractGroupProgress.DownContract,
                        //    OperatorId = CurrentUserName,
                        //    Operator = CurrentUserDisplayName,
                        //    OperateDate = DateTime.UtcNow.ToLocalDateTime(),
                        //    Type = ProcessLogType.Success,
                        //    NotContractGroupUsers = "",
                        //    Remark = "下载合同"
                        //};

                        //给pdf添加水印  https://www.starlu.com/  打印时间

                        //WatermarkHelper.AddWatermarkToPdf(stream, ms,
                        //    "https://www.starlu.com/ " + System.DateTime.Now.ToLongTimeString());

                        //var pdf = WatermarkHelper.AddWatermarkToPdf(stream, "https://www.starlu.com/ " + System.DateTime.UtcNow.AddHours(8).ToLocalTime());

                        //MemoryStream ms = new MemoryStream(pdf);

                        //return File(ms, contentType, decodeFileName.ReplaceLast(".", "-" + blob.Id + "."));
                    }
                    return File(stream, contentType, decodeFileName.ReplaceLast(".", "-" + blob.Id + "."));
                }
                else
                {
                    return Json(new { ResultType = ServiceResultType.Error, Message = "不支持所保存的文件格式。" });
                }
            }
            return Json(new { ResultType = ServiceResultType.Error, Message = "未找到文件。" });
        }
        //[AuthenticateAndAuthorizeTenant]
        [HttpGet]
        public void PrintPDF(string blobId, string userId)
        {
            if (string.IsNullOrEmpty(userId))
                userId = TenantName;
            var tenant = TenantStore.GetTenantByName(userId).Result;
            var blob = BlobUtil.GetBlobById(tenant, CurrentUserId, blobId);
            if (blob != null && blob.Data != null && blob.Data.Length > 0)
            {
                //MemoryStream PDFData = new MemoryStream(blob.Data);
                //var pdf = WatermarkHelper.AddWatermarkToPdf(PDFData, "https://www.starlu.com/ " + System.DateTime.Now.ToLocalTime());
                //System.Web.HttpContext.Current.Response.Clear();
                //System.Web.HttpContext.Current.Response.ClearContent();
                //System.Web.HttpContext.Current.Response.ClearHeaders();
                //System.Web.HttpContext.Current.Response.ContentType = "application/pdf";
                //System.Web.HttpContext.Current.Response.Charset = string.Empty;
                //System.Web.HttpContext.Current.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
                //System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=" + blob.FileName.UnicodeToChinese().Replace(" ", "").Replace(":", "-") + ".pdf");
                //System.Web.HttpContext.Current.Response.OutputStream.Write(pdf.ToArray(), 0, pdf.ToArray().Length);
                //System.Web.HttpContext.Current.Response.OutputStream.Flush();
                //System.Web.HttpContext.Current.Response.OutputStream.Close();
            }

        }


        #endregion Image & pdf & file

        #region 选小图标控件: Shared/_SelectUserPartial.cshtml
        [HttpGet]
        public PartialViewResult _SelectIconPartial()
        {
            return PartialView();
        }

        #endregion 选小图标控件: Shared/_SelectUserPartial.cshtml

        #region 选人控件: Shared/_SelectUserPartial.cshtml

        /// <summary>
        /// 获取所有的部门信息及下属员工
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public JsonResult GetRootOrganizationsWithUsers(List<string> roleIds)
        {
            //var roleIdList = new List<string>();
            //if (!string.IsNullOrEmpty(roleIds))
            //{
            //    roleIdList = roleIds.Split(',').ToList();
            //}
            var res = AccountApiService.GetOrganizationsWithUsersByRoleIds(roleIds).Result;
            var firstOrg = res.FirstOrDefault();
            if (firstOrg != null)
                firstOrg.@checked = true;
            return this.Json(new { deptInfos = res });
        }
        [HttpGet]
        public JsonResult GetRootOrganizationsWithUsers()
        {
            var res = AccountApiService.GetOrganizationsWithUsers();
            return Json(res);
        }

        /// <summary>
        /// 获取所有的部门信息及下属员工(erp)
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public JsonResult GetRootOrganizationsAndUsers(List<string> roleIds, string departName, string departCode, string userName, string userCode, string searchKey, int pageIndex = 1, int pageSize = 10)
        {
            var searchModel = new RootOrgWithUsersPaginatedSearchDTO()
            {
                Appid = CurrentOperationApplicationId,
                RoleIds = roleIds,
                DepartName = departName,
                DepartCode = departCode,
                UserName = userName,
                UserCode = userCode,
                SearchKey = searchKey,
                PageIndex = pageIndex,
                PageSize = pageSize,
            };
            var res = AccountApiService.GetPaginatedOrganizationsWithUsersByFilter(searchModel).Result;
            var firstOrg = res.rows.FirstOrDefault();
            if (firstOrg != null)
                firstOrg.@checked = true;
            return Json(res);
            //return this.Json(new { deptInfos = res });
        }
        /// <summary>
        /// 获取相关部门以及角色信息及下属员工
        /// </summary>
        /// <param name="roleIds"></param>
        /// <param name="depIds"></param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult GetRootOrgWithUsersByRoleIdsAndOrgids(List<string> roleIds, List<int> depIds)
        {
            var searchModel = new RootOrgWithUsersSearchDTO()
            {
                RoleIds = roleIds,
                DepIds = depIds,
            };
            var res = AccountApiService.GetOrgsWithUsersByRoleIdsAndOrgids(searchModel).Result;
            var firstOrg = res.FirstOrDefault();
            if (firstOrg != null)
                firstOrg.@checked = true;
            return this.Json(new { deptInfos = res });
        }

        [HttpGet]
        public JsonResult GetUserByorgFid(Guid orgfid)
        {
            var res = AccountApiService.GetUserByorgFid(orgfid);
            return this.Json(new { userInfos = res });

        }

        #endregion 选人控件: Shared/_SelectUserPartial.cshtml

        #region 选部门 未实现相关视图：Shared/_SelectOrganizationPartial.cshtml
        /// <summary>
        /// 获取所有部门信息(树)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public JsonResult GetRootOrganizations()
        {
            var res = AccountApiService.GetRootOrganizations();
            return this.Json(new { deptInfos = res });
        }
        #endregion

        #region 选国民经济分类 未实现相关视图：Shared/_SelectIndustryClassficationPartial.cshtml
        /// <summary>
        /// 获取所有国民经济分类信息(树)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public JsonResult GetRootIndustryClassfications()
        {
            return base.GetServiceJsonResult(() =>
            {
                return DictionaryApiService.GetRootIndustryClassfications();
            });
        }
        #endregion

        #region 选择省市控件  未实现相关视图：Shared/_SelectLocationPartial.cshtml

        /// <summary>
        /// 获取省份列表数据
        /// </summary>
        /// <returns></returns>
        protected SelectList GetProvinceList()
        {
            var results = ServiceWrapper.Invoke(
                "ControllerBase",
                "GetProvinceList",
                () => DictionaryApiService.GetAllProvinces(), 
                Logger);

            var list = new List<SelectListItem>();
            if (results.ResultType != ServiceResultType.Success)
                return new SelectList(list);

            var codeList = results.Result;
            if (codeList != null)
            {
                list = codeList.Select(model => new SelectListItem
                {
                    Text = model.Name,
                    Value = model.ProvinceId.ToString()
                }).ToList();
            }

            return new SelectList(list, "Value", "Text");
        }

        /// <summary>
        /// 获取省份信息
        /// </summary>
        /// <returns></returns>
        public JsonResult LoadProvinceList()
        {
            return base.GetServiceJsonResult(() =>
            {
                return DictionaryApiService.GetAllProvinces();
            });
        }

        /// <summary>
        /// 获取城市信息
        /// </summary>
        /// <returns></returns>
        public JsonResult LoadCityList()
        {
            return base.GetServiceJsonResult(() =>
            {
                return DictionaryApiService.GetAllCities();
            });
        }

        /// <summary>
        /// 根据省份Id，获取城市信息
        /// </summary>
        /// <param name="provinceID">省份Id</param>
        /// <returns></returns>
        public JsonResult LoadCitiesByProvinceId(int provinceID)
        {
            return base.GetServiceJsonResult(() =>
            {
                return DictionaryApiService.GetCitiesByProvinceId(provinceID);
            });
        }

        #endregion 选择省市控件

        [HttpGet]
        public JsonResult GetAllPermissions()
        {
            var allPermissions = MVC.Core.Extension.PermissionData.AllPermissions;
            return Json(allPermissions);
        }

        /// <summary>
        /// 树形选中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="checkList">选中的节点</param>
        /// <param name="scoreList">所有节点</param>
        /// <returns></returns>
        protected List<T> GetTreeNodeSimpleWithChildren<T>(ICollection<int> checkList, List<T> scoreList) where T : TreeNodeSimpleDTO<T>
        {
            foreach (var dto in scoreList)
            {
                if (dto.children.Any())
                {
                    if (checkList.Contains(dto.id))
                        dto.@checked = true;
                    GetTreeNodeSimpleWithChildren(checkList, dto.children);
                }
                else
                {
                    if (checkList.Contains(dto.id))
                    {
                        dto.@checked = true;
                    }
                }
            }
            return scoreList;
        }

    }
}